import { ref, onMounted, onUnmounted, watchEffect } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

/**
 * Three.js场景管理组合式函数
 * @param {Object} options - 场景配置选项
 * @param {HTMLElement} options.container - 渲染容器元素
 * @param {Object} options.cameraConfig - 相机配置
 * @param {Object} options.rendererConfig - 渲染器配置
 * @returns {Object} 场景相关对象和方法
 */
export function useThreeScene(options = {}) {
  // 场景相关对象
  const scene = ref(null)
  const camera = ref(null)
  const renderer = ref(null)
  const controls = ref(null)
  const animationId = ref(null)
  const clock = ref(null)
  
  // 默认配置
  const defaultOptions = {
    cameraConfig: {
      fov: 75,
      near: 0.1,
      far: 1000,
      position: { x: 0, y: 0, z: 5 }
    },
    rendererConfig: {
      antialias: true,
      alpha: true,
      shadowMap: {
        enabled: true,
        type: THREE.PCFSoftShadowMap
      }
    }
  }
  
  const mergedOptions = {
    ...defaultOptions,
    ...options,
    cameraConfig: {
      ...defaultOptions.cameraConfig,
      ...options.cameraConfig
    },
    rendererConfig: {
      ...defaultOptions.rendererConfig,
      ...options.rendererConfig
    }
  }
  
  // 初始化场景
  const initScene = () => {
    if (!mergedOptions.container) {
      console.error('容器元素未提供')
      return
    }
    
    // 创建场景
    scene.value = new THREE.Scene()
    scene.value.background = null // 透明背景
    
    // 创建相机
    const container = mergedOptions.container
    const aspect = container.clientWidth / container.clientHeight
    
    camera.value = new THREE.PerspectiveCamera(
      mergedOptions.cameraConfig.fov,
      aspect,
      mergedOptions.cameraConfig.near,
      mergedOptions.cameraConfig.far
    )
    
    camera.value.position.set(
      mergedOptions.cameraConfig.position.x,
      mergedOptions.cameraConfig.position.y,
      mergedOptions.cameraConfig.position.z
    )
    
    // 创建渲染器
    renderer.value = new THREE.WebGLRenderer({
      antialias: mergedOptions.rendererConfig.antialias,
      alpha: mergedOptions.rendererConfig.alpha
    })
    
    // 配置渲染器
    renderer.value.setSize(container.clientWidth, container.clientHeight)
    renderer.value.setPixelRatio(window.devicePixelRatio)
    
    // 配置阴影
    if (mergedOptions.rendererConfig.shadowMap.enabled) {
      renderer.value.shadowMap.enabled = true
      renderer.value.shadowMap.type = mergedOptions.rendererConfig.shadowMap.type
    }
    
    // 添加渲染器DOM元素到容器
    container.appendChild(renderer.value.domElement)
    
    // 创建轨道控制器
    controls.value = new OrbitControls(camera.value, renderer.value.domElement)
    controls.value.enableDamping = true
    controls.value.dampingFactor = 0.05
    
    // 创建时钟
    clock.value = new THREE.Clock()
  }
  
  // 渲染函数
  const animate = () => {
    animationId.value = requestAnimationFrame(animate)
    
    // 更新控制器
    if (controls.value) {
      controls.value.update()
    }
    
    // 渲染场景
    renderer.value.render(scene.value, camera.value)
  }
  
  // 调整大小
  const resize = () => {
    if (!camera.value || !renderer.value || !mergedOptions.container) return
    
    const container = mergedOptions.container
    const aspect = container.clientWidth / container.clientHeight
    
    // 更新相机
    camera.value.aspect = aspect
    camera.value.updateProjectionMatrix()
    
    // 更新渲染器
    renderer.value.setSize(container.clientWidth, container.clientHeight)
  }
  
  // 性能优化：使用防抖函数处理resize
  const debounce = (func, delay) => {
    let timeoutId
    return (...args) => {
      clearTimeout(timeoutId)
      timeoutId = setTimeout(() => func.apply(null, args), delay)
    }
  }
  
  const debouncedResize = debounce(resize, 100)
  
  // 监听容器大小变化
  const observeContainer = () => {
    if (!mergedOptions.container) return
    
    const resizeObserver = new ResizeObserver(entries => {
      for (let entry of entries) {
        debouncedResize()
      }
    })
    
    resizeObserver.observe(mergedOptions.container)
    
    return resizeObserver
  }
  
  // 生命周期钩子
  onMounted(() => {
    initScene()
    animate()
    
    // 添加事件监听
    window.addEventListener('resize', debouncedResize)
    
    // 使用ResizeObserver监听容器大小变化
    const resizeObserver = observeContainer()
    
    // 清理函数
    onUnmounted(() => {
      if (resizeObserver) {
        resizeObserver.disconnect()
      }
      
      if (animationId.value) {
        cancelAnimationFrame(animationId.value)
      }
      
      window.removeEventListener('resize', debouncedResize)
      
      if (renderer.value && mergedOptions.container) {
        mergedOptions.container.removeChild(renderer.value.domElement)
        renderer.value.dispose()
      }
      
      // 清理场景资源
      if (scene.value) {
        scene.value.dispose()
      }
    })
  })
  
  // 暴露场景控制方法
  const addObject = (object) => {
    if (scene.value && object) {
      scene.value.add(object)
    }
  }
  
  const removeObject = (object) => {
    if (scene.value && object) {
      scene.value.remove(object)
    }
  }
  
  const setCameraPosition = (x, y, z) => {
    if (camera.value) {
      camera.value.position.set(x, y, z)
      camera.value.updateMatrixWorld()
    }
  }
  
  const lookAt = (x, y, z) => {
    if (camera.value) {
      camera.value.lookAt(x, y, z)
    }
  }
  
  // 公共API
  return {
    scene,
    camera,
    renderer,
    controls,
    clock,
    addObject,
    removeObject,
    setCameraPosition,
    lookAt,
    resize
  }
}